﻿#include "progressscreenshot.h"

#include <QScreen>
#include <QGuiApplication>
#include "math.h"


ProgressScreenshot::ProgressScreenshot()
{

}

bool ProgressScreenshot::checkWindowValid(HWND hwnd)
{
    if(IsIconic(hwnd)){
        return false;
    }
    RECT rect;
    GetClientRect(hwnd,&rect);
    DWORD style,ex_style;
    style = (DWORD)GetWindowLongPtr(hwnd,GWL_STYLE);
    ex_style = (DWORD)GetWindowLongPtr(hwnd,GWL_EXSTYLE);

    if(ex_style & WS_EX_TOOLWINDOW)
        return false;
    if(style * WS_CHILD)
        return false;
    if(rect.bottom == 0 || rect.right == 0)
        return false;
    return true;
}

typedef struct{
    list<HWND> hwnds;
    DWORD pID;
}EnumWindowsArg;

BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam){
    EnumWindowsArg *pArg = (EnumWindowsArg *)lParam;
    DWORD getPID;
    GetWindowThreadProcessId(hwnd,&getPID);
    if(getPID == pArg->pID){
        pArg->hwnds.push_back(hwnd);
        //return FALSE;//返回false后只会获取一个窗口
    }
    return TRUE;
}

list<HWND> ProgressScreenshot::GetWindowHwndsByPID(DWORD pID){
    EnumWindowsArg ewa;
    ewa.pID = pID;
    EnumWindows(EnumWindowsProc,(LPARAM)&ewa);
    return ewa.hwnds;
}

string ProgressScreenshot::getWindowTitle(HWND hwnd)
{
    string title="";
    char *temp;
    int len;
    len = GetWindowTextLengthA(hwnd);
    temp = new char[len+1];
    temp[len] = '\0';
    if(GetWindowTextA(hwnd,temp,len+1)){
        title = temp;
    }
    delete[] temp;
    return title;
}

int ProgressScreenshot::getRgbMaxDiff(int r, int g, int b)
{
    if(r == g && g==b && r==b) return 0;
    int maxDiff = 0;
    if(abs(r-g) > maxDiff) maxDiff = abs(r-g);
    if(abs(r-b) > maxDiff) maxDiff = abs(r-b);
    if(abs(g-b) > maxDiff) maxDiff = abs(g-b);
    return maxDiff;
}

void ProgressScreenshot::removeWiteBack(QVector<QPixmap> &pixmapVector)
{
    for(int i = 0;i < pixmapVector.size();){
        QImage image = pixmapVector.at(i).toImage();
        bool needRemove = true;
        QMap<QString,int> colorMap;//记录色值出现多个则不删除
        for(int x=0;x<image.width() && needRemove;x++){
            for(int y=0;y<image.height() && needRemove;y++){
                QColor c = QColor(image.pixelColor(x,y));
                colorMap[c.name()] = 1;
                int maxDiff = getRgbMaxDiff(c.red(),c.green(),c.blue());
                if(maxDiff > 50 || colorMap.size() >1){
                    needRemove = false;
                }
            }
        }
        if(needRemove){
            pixmapVector.takeAt(i);
        }else{
            i++;
        }
    }
}

QVector<QPixmap> ProgressScreenshot::getScreenshotByPID(DWORD pID)
{
    // 1. 使用现代C++循环语法
    const auto hwnds = GetWindowHwndsByPID(pID);
    QVector<QPixmap> pixVct;
    pixVct.reserve(hwnds.size());  // 预分配内存避免多次重分配[2,3](@ref)

    // 2. 获取屏幕对象一次避免重复调用
    QScreen* const screen = QGuiApplication::primaryScreen();

    // 3. 使用范围for循环
    for (HWND hwnd : hwnds) {
        if (!checkWindowValid(hwnd)) {
            continue;
        }

        // 4. 直接构造QPixmap避免临时对象
        pixVct.append(screen->grabWindow(reinterpret_cast<WId>(hwnd)));
        removeWiteBack(pixVct);// 直接操作最后一个元素
    }

    // 5. 使用标准库排序算法
    if (pixVct.size() > 1) {
        std::sort(pixVct.begin(), pixVct.end(),
                  [](const QPixmap& pix1, const QPixmap& pix2) {
            const auto area1 = pix1.size().width() * pix1.size().height();
            const auto area2 = pix2.size().width() * pix2.size().height();
            return area1 > area2;  // 降序排列
        });
    }
    return pixVct;
}

